package com.bbs.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bbs.dto.DialogDto;
import com.bbs.exception.BusinessException;
import com.bbs.feign.UserFriendshipClient;
import com.bbs.mapper.MessageMapper;
import com.bbs.pojo.Message;
import com.bbs.pojo.User;
import com.bbs.pojo.dto.MessageDto;
import com.bbs.pojo.dto.message.UserMessageContent;
import com.bbs.service.ChatService;
import com.bbs.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ChatServiceImpl implements ChatService {
    @Autowired
    MessageService messageService;
    @Autowired
    MessageMapper messageMapper;
    @Autowired
    UserFriendshipClient userFriendshipClient;

    @Override
    public boolean sendUserMessage(String senderId, String receiverId, String text) {
        if(senderId.equals(receiverId)){
            throw new BusinessException("不能给自己发送消息");
        }

        //TODO: 判断好友关系

        MessageDto messageDto = new MessageDto();

        UserMessageContent userMessageContent = new UserMessageContent();
        userMessageContent.setText(text);
        messageDto.setContent(userMessageContent);
        messageDto.setType(userMessageContent.messageType());

        messageDto.setSenderId(senderId);
        messageDto.setReceiverId(receiverId);
        messageDto.setAcknowledged(false);

        return messageService.sendMessage(messageDto);
    }

    @Override
    public List<DialogDto> getDialogs(String senderId, String receiverId) {
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> {
            wrapper
                    .and(wrapper2-> wrapper2.eq("sender_id", senderId).eq("receiver_id", receiverId))
                    .or(wrapper2-> wrapper2.eq("sender_id", receiverId).eq("receiver_id", senderId));
        });
        queryWrapper.eq("type", UserMessageContent.MESSAGE_TYPE);
        queryWrapper.orderBy(true, true, "sent_time");
        List<Message> messages = messageService.list(queryWrapper);

        //确认消息
        acknowledgeUserMessage(receiverId, senderId);

        return messages.stream().map(this::dialogDtoMapper).collect(Collectors.toList());
    }

    @Override
    public List<DialogDto> getDialogsAfter(String senderId, String receiverId, LocalDateTime time) {
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> {
            wrapper
                    .and(wrapper2-> wrapper2.eq("sender_id", senderId).eq("receiver_id", receiverId))
                    .or(wrapper2-> wrapper2.eq("sender_id", receiverId).eq("receiver_id", senderId));
        });
        queryWrapper.eq("type", UserMessageContent.MESSAGE_TYPE);
        queryWrapper.orderBy(true, true, "sent_time");
        queryWrapper.gt("sent_time", time);
        List<Message> messages = messageService.list(queryWrapper);

        //确认消息
        acknowledgeUserMessageAfter(receiverId, senderId, time);

        return messages.stream().map(this::dialogDtoMapper).collect(Collectors.toList());
    }

    @Override
    public List<MessageDto> getLastUserMessageGroupBySender(String receiverId) {
        List<Message> messages = messageMapper.getLastUserMessageGroupBySender(receiverId, UserMessageContent.MESSAGE_TYPE);
        return messages.stream().map(MessageDto::new).collect(Collectors.toList());
    }

    /**
     * 确认某个时间之后的消息
     */
    private boolean acknowledgeUserMessageAfter(String senderId, String receiverId, LocalDateTime time) {
        UpdateWrapper<Message> updateWrapper = new UpdateWrapper<>();
        updateWrapper.ge("sent_time", time);
        updateWrapper.eq("sender_id", senderId);
        updateWrapper.eq("receiver_id", receiverId);
        updateWrapper.eq("type", UserMessageContent.MESSAGE_TYPE);
        updateWrapper.set("acknowledged", true);
        return messageService.update(updateWrapper);
    }

    /**
     * 确认所有消息
     */
    private boolean acknowledgeUserMessage(String senderId, String receiverId){
        UpdateWrapper<Message> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("sender_id", senderId);
        updateWrapper.eq("receiver_id", receiverId);
        updateWrapper.eq("type", UserMessageContent.MESSAGE_TYPE);
        updateWrapper.eq("acknowledged", false);
        updateWrapper.set("acknowledged", true);
        return messageService.update(updateWrapper);
    }

    @Override
    public List<String> getAcknowledgedUsers(String receiverId) {
        Message message = new Message();
        message.setAcknowledged(false);
        message.setReceiverId(receiverId);
        QueryWrapper<Message> queryWrapper = new QueryWrapper<>(message);
        queryWrapper.groupBy("sender_id");
        queryWrapper.select("sender_id");
        List<Message> messages = messageService.list(queryWrapper);
        List<String> senderIds = new ArrayList<>();
        for (Message message1 : messages) {
            senderIds.add(message1.getSenderId());
        }

        return senderIds;
    }

    private DialogDto dialogDtoMapper(Message message){
        DialogDto dialogDto = new DialogDto();
        UserMessageContent userMessageContent = JSON.parseObject(message.getContent(), UserMessageContent.class);
        dialogDto.setContent(userMessageContent.getText());
        dialogDto.setSenderId(message.getSenderId());
        dialogDto.setSendTime(message.getSentTime());
        return dialogDto;
    }
}
